package com.zhss.seckill.flash.sale.controller;

import com.alibaba.fastjson.JSONObject;
import com.zhss.seckill.common.RedisCluster;
import com.zhss.seckill.common.RocketMQProducer;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 秒杀抢购请求处理组件
 */
@RestController
@RequestMapping("/seckill/flash/sale")
public class FlashSaleController {

    /**
     * 用户对商品进行抢购，默认限定每个商品最多只能抢购一件
     * @param userId 用户id
     * @param productId 商品id
     * @return
     */
    @GetMapping("/")
    public String flashSale(Long userId, Long productId) {
        // 写秒杀抢购的代码，核心主体是Lua脚本
        // 但是这里要做一个多机器库存分片负载均衡的事情
        // 如果发现某个库存分片为0，此时需要做自动的库存分片迁移的事情
        RedisCluster redisCluster = RedisCluster.getInstance();
        Boolean flashSaleResult = redisCluster.flashSale(userId, productId);

        // 如果秒杀抢购成功了，发送消息到MQ去进行异步下单
        if(flashSaleResult) {
            DefaultMQProducer producer = RocketMQProducer.getInstance().getProducer();

            try {
                JSONObject flashSaleSuccessInform = new JSONObject();
                flashSaleSuccessInform.put("userId", userId);
                flashSaleSuccessInform.put("productId", productId);

                Message message = new Message(
                        "flash_sale_success_inform",
                        null,
                        flashSaleSuccessInform.toJSONString().getBytes(RemotingHelper.DEFAULT_CHARSET)
                );
                SendResult sendResult = producer.send(message);

                System.out.printf("%s%n", sendResult);
                System.out.println("推送秒杀抢购成功通知到MQ......");
            } catch(Exception e) {
                System.err.println("秒杀抢购成功通知推送到MQ失败：" + e);
                // 完全可以把消息写入本地磁盘做一个积压，搞一个后台线程不停的尝试MQ是否恢复
                // 如果MQ恢复了，就可以把本地磁盘积压的消息发送出去
                return "秒杀抢购成功，但是推送消息到MQ失败";
            }

            return "秒杀抢购成功";
        } else {
            return "秒杀抢购失败";
        }
    }

}
